package com.openlogic.logic.concurent;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import com.openlogic.datasource.api.vo.SqlConsoleVo;

import jodd.db.QueryMapper;
import jodd.db.connection.ConnectionProvider;
import jodd.db.oom.DbOomQuery;

/**
* @ClassName: DataTableDetailHander
* @Description: 表结果集处理器
* @author weiyongpeng
* @date 2024年11月24日 下午6:15:34
 */
public class DataTableDetailHander extends CallableTemplate<SqlConsoleVo> {

    private CountDownLatch latch;

    private ConnectionProvider connectionProvider;

    private String sql;
    
    private String countSql;
    
    private List<Map<String, String>> columnMeta;
    
    private static SqlConsoleVo sqlConsoleVo = new SqlConsoleVo();

    public DataTableDetailHander(CountDownLatch latch, ConnectionProvider connectionProvider, String pageSql, String countSql, 
    		List<Map<String, String>> columnMeta) {
		this.latch = latch;
		this.connectionProvider = connectionProvider;
		this.sql = pageSql;
		this.countSql = countSql;
		this.columnMeta = columnMeta;
	}

	@Override
	public void beforeProcess() {
		long count = DbOomQuery.query(connectionProvider.getConnection(), countSql).executeCount();
//		Integer count = jdbcTemplate.queryForObject(countSql, Integer.class);
		latch.countDown();
		sqlConsoleVo.setCount(Integer.parseInt(String.valueOf(count)));
	}

	@Override
    public SqlConsoleVo process() {
        log.info("执行sql:" + sql);
        long start = System.currentTimeMillis();
        // 将查询数据存储到数据中
        List<Map<String, Object>> dataList = new ArrayList<>();
        // 存储列名的数组
        List<String> columnList = new LinkedList<>();
        // 执行sql
        DbOomQuery.query(connectionProvider.getConnection(), sql).list(new QueryMapper<List<String>>() {

			@Override
			public List<String> process(ResultSet rs) throws SQLException {
				// 获取结果集的元数据信息
                ResultSetMetaData rsmd = rs.getMetaData();
                // 获取列字段的个数
                int colunmCount = rsmd.getColumnCount();
                for (int i = 1; i <= colunmCount; i++) {
                    // 获取所有的字段名称
                    columnList.add(rsmd.getColumnName(i));
                }
                while(rs.next()){
                    Map<String, Object> map = new HashMap<>();
                    for (int i = 1; i <= colunmCount; i++) {
                        // 获取列名
                        String columnName = rsmd.getColumnName(i);
                        Object val = null;
                        switch (rsmd.getColumnType(i)) {
                            case Types.ARRAY:
                                val = rs.getArray(columnName);
                                break;
                            case Types.BIGINT:
                                val = rs.getLong(columnName);
                                break;
                            case Types.BOOLEAN:
                            case Types.BIT:
                                val = rs.getBoolean(columnName);
                                break;
                            case Types.DOUBLE:
                                val = rs.getDouble(columnName);
                                break;
                            case Types.FLOAT:
                            case Types.REAL:
                                val = rs.getFloat(columnName);
                                break;
                            case Types.INTEGER:
                                val = rs.getInt(columnName);
                                break;
                            case Types.NVARCHAR:
                            case Types.NCHAR:
                            case Types.LONGNVARCHAR:
                                val = rs.getNString(columnName);
                                break;
                            case Types.VARCHAR:
                            case Types.CHAR:
                            case Types.LONGVARCHAR:
                                val = rs.getString(columnName);
                                break;
                            case Types.TINYINT:
                            case Types.BINARY:
                            case Types.VARBINARY:
                                val = rs.getByte(columnName);
                                break;
                            case Types.SMALLINT:
                                val = rs.getShort(columnName);
                                break;
                            case Types.DATE:
                                val = rs.getDate(columnName);
                                break;
                            case Types.TIME:
                                val = rs.getTime(columnName);
                                break;
                            case Types.TIMESTAMP:
                                val = rs.getTimestamp(columnName);
                                break;
                            case Types.NUMERIC:
                            case Types.DECIMAL:
                                val = rs.getBigDecimal(columnName);
                                break;
                            case Types.BLOB:
                            case Types.CLOB:
                            case Types.LONGVARBINARY:
                            case Types.DATALINK:
                            case Types.REF:
                            case Types.STRUCT:
                            case Types.DISTINCT:
                            case Types.JAVA_OBJECT:
                                break;
                            default:
                                val = rs.getObject(columnName);
                                break;
                        }
                        map.put(columnName, val);
                    }
                    dataList.add(map);
                }
				return null;
			}
        	
        });
        
        latch.countDown();
        long end = System.currentTimeMillis();
        log.info("线程查询数据用时:" + (end - start) + "ms");
        sqlConsoleVo.setSql(sql);
        sqlConsoleVo.setColumnList(columnList);
        sqlConsoleVo.setColumnMeta(columnMeta);
        sqlConsoleVo.setDataList(dataList);
        sqlConsoleVo.setTime(end - start);
        return sqlConsoleVo;
    }
}
